package com.ciwong.epaper.modules.me.util;

import android.database.sqlite.SQLiteException;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.ciwong.epaper.application.EpaperConstant;
import com.ciwong.epaper.modules.epaper.bean.Answer;
import com.ciwong.epaper.modules.epaper.bean.ModuleInfo;
import com.ciwong.epaper.modules.epaper.dao.EpaperDao;
import com.ciwong.epaper.modules.me.dao.db.db.StudyRecordDB;
import com.ciwong.epaper.util.ALiYunManager;
import com.ciwong.epaper.util.FeedbackUtil;
import com.ciwong.eventbus.EventBus;
import com.ciwong.libs.utils.CWLog;
import com.ciwong.libs.utils.FileUtils;
import com.ciwong.mobilelib.i.BaseCallBack;
import com.ciwong.mobilelib.utils.ThreadTask;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by res-mingyang on 2015/7/31.
 */
public class UploadFileHelper {
    private static UploadFileHelper instance;

    private List<UploadFileTask> mUploadFileList = new ArrayList<UploadFileTask>();

    private static final int SUBMIT_WORK_TOKEN_FAIL = -100;// 用户token过期

    private static final int SUBMIT_WORK_CONNECT_FAIL = -101;// 提交答案接口连接失败

    private static final int FILE_URL_EMPTY = -102;// 文件上传返回的url是空

    private static final int EXIT_PAUSE = -103;// 退出登录，操作中断

    public static final int ERROR_CODE_FILE_EXISTS = -104;// 错误码:文件不存在

    public static final int ERROR_CODE_SOCKET_TIME_OUT = -105;// socket超时

    private int mWorkType = 0;

    private BaseCallBack mBaseCallBack;
    private Handler mHandler;

    private ALiYunManager.ALiYunListener listener = new ALiYunManager.ALiYunListener() {
        @Override
        public void onProgress(Object tag, long currentSize, long totalSize) {
            Answer tempAnswer = new Answer();
            tempAnswer.setDoWorkLocalPath(String.valueOf(tag));
            UploadFileTask tempTask = new UploadFileTask(tempAnswer, 0);
            int indexOf = mUploadFileList.indexOf(tempTask);
            if (indexOf >= 0) {
                UploadFileTask task = mUploadFileList.get(indexOf);
                task.answer.setSubmitStatus(Answer.SubmitStatus.WORK_SUBMITING);
                task.answer.setProgress((int) (currentSize * 100 / totalSize));
                EventBus.getDefault().post(task.answer);
            }
        }


        @Override
        public void onSuccess(final Object tag, final String url) {

            String logDesc;
            if (null != tag) {
                logDesc = tag.toString();
            } else {
                logDesc = " ";
            }

            FeedbackUtil.getInstance().addFeedbackLog(FeedbackUtil.FEEDBACK_TYPE_ALIYUN_SUBMIT_WORK_RESULT, logDesc, EpaperConstant.UPLOAD_STATE_SUCCESS);


            synchronized (mUploadFileList) {
                String path = String.valueOf(tag);
                for (UploadFileTask task : mUploadFileList) {
                    if (task != null && path != null && task.answer != null
                            && task.answer.getDoWorkLocalPath() != null
                            && path.equals(task.answer.getDoWorkLocalPath())) {
                        mUploadFileList.remove(task);
                        checkUploadResult(url, task, mWorkType);
                    }
                }
            }


        }

        @Override
        public void onFailure(final Object tag, final int errorCode) {

            String logDesc;
            if (null != tag) {
                logDesc = tag.toString() + "######" + errorCode;
            } else {
                logDesc = " ";
            }

            FeedbackUtil.getInstance().addFeedbackLog(FeedbackUtil.FEEDBACK_TYPE_ALIYUN_SUBMIT_WORK_RESULT, logDesc, EpaperConstant.UPLOAD_STATE_FAIL);

            synchronized (mUploadFileList) {
                String path = String.valueOf(tag);
                for (UploadFileTask task : mUploadFileList) {
                    if (task != null && path != null
                            && path.equals(task.answer.getDoWorkLocalPath())) {
                        task.answer.setProgress(0);
                        mUploadFileList.remove(task);
                        updateSendStatus(task.answer,
                                Answer.SubmitStatus.WORK_FILE_SUBMIT_FAILE,
                                getErrorMsg(errorCode));
                    }
                }
            }
        }
    };

    /**
     * 获取错误提示消息
     *
     * @param errorCode
     * @return
     */
    private String getErrorMsg(int errorCode) {
        return "作业提交失败,点击重新提交（" + errorCode + ")";
    }

    private UploadFileHelper() {
        ALiYunManager.getInstance().registerListener(listener);
    }

    public static UploadFileHelper getInstance() {
        if (instance == null) {
            instance = new UploadFileHelper();
        }
        return instance;
    }

    /**
     * 提交答案
     */
    public synchronized void submitAnswer(final Answer answer,
                                          final long userId, final BaseCallBack baseCallBack, Handler handler, int workType) {

        mWorkType = workType;
        mBaseCallBack = baseCallBack;
        mHandler = handler;

        switch (answer.getSubmitStatus()) {
            case Answer.SubmitStatus.WORK_FILE_SUBMIT_FAILE:
                break;
            case Answer.SubmitStatus.WORK_SUBMIT_FAILE:
                baseCallBack.failed(null);
                break;
            case Answer.SubmitStatus.SUBMIT_WORK_NO_CLASS_ERROR:
                sendAnswerJson(answer, baseCallBack, handler, workType);
                return;
            case Answer.SubmitStatus.WORK_SUBMITING:
                if (answer != null & answer.getDoWorkPackageUrl() != null && answer.getDoWorkPackageUrl().startsWith("http://")) {
                    if (baseCallBack != null && handler != null) {
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                baseCallBack.success();
                            }
                        });
                    }

                    sendAnswerJson(answer, baseCallBack, handler, workType);

                    return;
                }
                break;
            case Answer.SubmitStatus.WORK_SUBMIT_SUCCUED:
                return;
        }
        synchronized (mUploadFileList) {
            UploadFileTask task = new UploadFileTask(answer, userId);
            if (mUploadFileList.contains(task)) {
                return;
            }
            mUploadFileList.add(task);
        }
        // ThreadTask.getInstance().executorOtherThread(new Runnable()
        // {
        // @Override
        // public void run()
        // {
        answer.setSubmitStatus(Answer.SubmitStatus.WORK_SUBMITING);
        long _id = StudyRecordDB.insertWorkData(answer);
        if (answer.get_id() == 0) {
            answer.set_id(_id);
        }
        EventBus.getDefault().post(answer);

        ALiYunManager.getInstance().add(answer.getDoWorkLocalPath(),
                answer.getDoWorkLocalPath());

        if (baseCallBack != null && handler != null) {
            handler.post(new Runnable() {

                @Override
                public void run() {
                    baseCallBack.success();
                }
            });
        }
    }

    private void sendAnswerJson(final Answer answer,
                                final BaseCallBack baseCallBack, final Handler handler, int workType) {
        if (answer.getSubmitStatus() != Answer.SubmitStatus.WORK_SUBMITING) {
            updateSendStatus(answer, Answer.SubmitStatus.WORK_SUBMITING, "");
        }
        Log.e("sendAnswerJson", "sendAnswerJson: workType ==" + workType);
        String json = answer.toString();
        try {
            JSONObject jsonObject = new JSONObject(json);
            String key = "workAnswers";
            if (jsonObject.has(key)) {
                JSONArray array = new JSONArray(answer.getWorkAnswers());
                jsonObject.remove(key);
                jsonObject.put(key, array);
                json = jsonObject.toString();
            }
        } catch (Exception e) {
            FeedbackUtil.getInstance().addFeedbackLog(FeedbackUtil.FEEDBACK_TYPE_SUBMIT_WORK, "Answer 对象转换成json 错误", "doworkId=="+answer.getWorkId());

            e.printStackTrace();
        }



        EpaperDao.getInstance().submitWork(json, workType, answer, new BaseCallBack() {
            @Override
            public void success(Object data) {
                baseCallBack.success(data);

                if (answer.getModuleId() == ModuleInfo.ModuleInfoId.MODULE_ID_TEST && !TextUtils.isEmpty(answer.getOldDoWorkId())) {
                    updateUnitTestWork(answer);
                }

                answer.setSubmitStatus(Answer.SubmitStatus.WORK_SUBMIT_SUCCUED);
                EventBus.getDefault().post(answer);
                CWLog.d("debug", "答案提交成功！");

                ThreadTask.getInstance().executorOtherThread(new Runnable() {
                    @Override
                    public void run() {


                        StudyRecordDB.deleteDataById(answer.get_id() + "");
                        FileUtils.delete(answer.getDoWorkLocalPath());


                    }
                }, ThreadTask.ThreadPeriod.PERIOD_HIGHT);
            }

            @Override
            public void failed(final Object data) {
                updateSendStatus(answer, Answer.SubmitStatus.WORK_SUBMIT_FAILE,
                        getErrorMsg(data instanceof AuthFailureError
                                ? SUBMIT_WORK_TOKEN_FAIL
                                : SUBMIT_WORK_CONNECT_FAIL));
                if (baseCallBack != null && handler != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            baseCallBack.failed(data);
                        }
                    });
                }
            }

            @Override
            public void failed(final int errorCode, final Object data) {
                updateSendStatus(answer, errorCode, getErrorMsg(errorCode));
                if (baseCallBack != null && handler != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            baseCallBack.failed(errorCode, data);
                        }
                    });
                }
            }
        });
    }

    /**
     * 更新旧的单元测试作业
     */
    private void updateUnitTestWork(final Answer answer) {
        EpaperDao.getInstance().updateUnitTestWork(answer.getOldDoWorkId(),
                new BaseCallBack() {
                    @Override
                    public void success(Object data) {
                        if (answer != null) {
                            EventBus.getDefault().post(answer);
                        }
                    }

                    @Override
                    public void failed(int errorCode, Object data) {

                    }

                    @Override
                    public void failed(Object data) {

                    }
                });
    }

    /**
     * 更新发送的状态
     */
    private void updateSendStatus(Answer answer, int status, String logInfo) {
        answer.setSubmitStatus(status);
        answer.setLogInfo(logInfo);
        EventBus.getDefault().post(answer);
        insertAnswer(answer);
    }

    public static class UploadFileTask {
        public Answer answer;

        public long userId;

        public UploadFileTask(Answer answer, long userId) {
            this.answer = answer;
            this.userId = userId;
        }

        @Override
        public boolean equals(Object o) {
            UploadFileTask task = (UploadFileTask) o;
            if (answer == null || answer.getDoWorkLocalPath() == null
                    || task.answer == null) {
                return false;
            }
            return answer.getDoWorkLocalPath()
                    .equals(task.answer.getDoWorkLocalPath());
        }
    }

    // /**
    // * 删除消息时同时要删除正在上传的任务
    // *
    // * @param messageData
    // * 被删除的消息
    // */
    // public void deleteUploadFile(final MessageData messageData)
    // {
    // ThreadTask.getInstance().executorOtherThread(new Runnable()
    // {
    // @Override
    // public void run()
    // {
    // synchronized (mUploadFileList)
    // {
    // for (int i = mUploadFileList.size() - 1; i >= 0; i--)
    // {
    // UploadFileTask task = mUploadFileList.get(i);
    // MessageData msg = task.mMessage;
    // if (msg != null && msg.equals(messageData))
    // {
    // mUploadFileList.remove(task);
    // for (int j = 0; j < mUploadFileList.size(); j++)
    // {
    // String path = mUploadFileList.get(j).path;
    // if (path != null && path.equals(task.path))
    // {
    // return;
    // }
    // }
    // AsyncUploadLargeFileManager.getInstance()
    // .cancleUplaod(task.path);
    // break;
    // }
    // }
    // }
    // }
    // }, ThreadPeriod.PERIOD_HIGHT);
    // }

    /**
     * 检验发送文件返回结果
     */
    private void checkUploadResult(String url, UploadFileTask task, int wrokType) {
        if (TextUtils.isEmpty(url)) {
            task.answer.setDoWorkPackageUrl(url);
            updateSendStatus(task.answer,
                    Answer.SubmitStatus.WORK_FILE_SUBMIT_FAILE,
                    getErrorMsg(FILE_URL_EMPTY));
        } else {
            task.answer.setDoWorkPackageUrl(url);
            // reNameDir(task.answer);
            insertAnswer(task.answer);


            if (null != mBaseCallBack && mHandler != null) {
                sendAnswerJson(task.answer, mBaseCallBack, mHandler, wrokType);

            } else if (null != mBaseCallBack) {
                sendAnswerJson(task.answer, mBaseCallBack, null, wrokType);
            } else {
                sendAnswerJson(task.answer, null, null, wrokType);

            }

        }
    }

    /**
     * 对本地的答案进行插入和更新操作
     *
     * @param answer
     */
    private void insertAnswer(final Answer answer) {
        ThreadTask.getInstance().executorDBThread(new Runnable() {
            @Override
            public void run() {

                try {

                    StudyRecordDB.insertWorkData(answer);

                } catch (SQLiteException sqLiteException) {

                }

            }
        }, ThreadTask.ThreadPeriod.PERIOD_HIGHT);
    }

    // private String splitJson(Answer answer)
    // {
    // JSONObject json = new JSONObject();
    // Class<?> classType = answer.getClass();
    // Field[] fields = answer.getClass().getDeclaredFields();
    // for (Field field : fields)
    // {
    // try
    // {
    // field.setAccessible(true);
    // String key = field.getName();
    // String firstLetter = key.substring(0, 1).toUpperCase();
    // // 获得和属性对应的getXXX()方法的名字
    // String getMethodName = "get" + firstLetter + key.substring(1);
    // Method getMethod = classType.getMethod(getMethodName,
    // new Class[]{});
    // // 调用原对象的getXXX()方法
    // String value = (String) getMethod
    // .invoke(answer, new Object[]{});
    // json.put(key, value);
    // }
    // catch (Exception e)
    // {
    // e.printStackTrace();
    // continue;
    // }
    // }
    // return json.toString();
    // }

 /*   private void reNameDir(Answer answer)
    {
        try
        {
            String savePath = answer.getDoWorkLocalPath();
            savePath = savePath.substring(0, savePath.lastIndexOf("."));
            File file = new File(savePath);
            String url = answer.getDoWorkPackageUrl();
            file.renameTo(new File(file.getParentFile().getAbsolutePath()
                    + File.separator + url.substring(url.lastIndexOf("/") + 1,
                            url.lastIndexOf("."))));
            Log.i("se7en",
                    file.getParentFile().getAbsolutePath() + File.separator
                            + url.substring(url.lastIndexOf("/") + 1,
                                    url.lastIndexOf(".")));
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }*/

    public UploadFileTask getUploadFileTask(UploadFileTask uploadFileTask) {
        if (mUploadFileList.contains(uploadFileTask)) {
            return mUploadFileList.get(mUploadFileList.indexOf(uploadFileTask));
        }
        return null;
    }

    private void stopUploadList() {
        synchronized (mUploadFileList) {
            for (int i = 0; i < mUploadFileList.size(); i++) {
                UploadFileTask task = mUploadFileList.get(i);
                if (task.answer.getSubmitStatus() == Answer.SubmitStatus.WORK_SUBMITING) {

                    ALiYunManager.getInstance().cancel(task.answer.getDoWorkLocalPath());

                    updateSendStatus(task.answer, Answer.SubmitStatus.WORK_FILE_SUBMIT_FAILE,
                            getErrorMsg(EXIT_PAUSE));
                }
            }
        }
    }

    /**
     * 释放资源
     */
    public void release() {
        stopUploadList();
        mUploadFileList.clear();
        ALiYunManager.getInstance().unRegisterListener(listener);
        instance = null;
    }

    /**
     * 获取正在上传的列表
     *
     * @return
     */
    public List<UploadFileTask> getUploadTaskList() {
        return this.mUploadFileList;
    }
}